﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using OfficeOpenXml;

namespace InspectionMAC.Config
{
    public static class DataStorageToExcelThread
    {
        private static Thread _storageThread = null;
        private static bool _isRunning = false;
        private static readonly BlockingCollection<SingleItemInfo> _dataQueue =
            new BlockingCollection<SingleItemInfo>(1000);
        private static readonly object _lock = new object();

        // Excel存储相关配置
        private const int BATCH_SIZE = 1; // 批量写入大小
        private static readonly List<SingleItemInfo> _batchBuffer = new List<SingleItemInfo>(BATCH_SIZE);
        private static readonly string _baseDataDirectory = Path.Combine("Data", "InspectionData"); // 基础数据目录

        // 静态构造函数确保路径初始化
        static DataStorageToExcelThread()
        {
            // 确保基础目录存在
            if (!Directory.Exists(_baseDataDirectory))
            {
                Directory.CreateDirectory(_baseDataDirectory);
            }
        }

        public static void Initialize()
        {
            if (_storageThread == null || !_storageThread.IsAlive)
            {
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                _isRunning = true;
                _storageThread = new Thread(StorageThreadProc);
                _storageThread.IsBackground = true;
                _storageThread.Start();
                Console.WriteLine("Excel存储线程已启动");
            }
        }

        public static void Stop()
        {
            _isRunning = false;
            if (_storageThread != null && _storageThread.IsAlive)
            {
                if (!_storageThread.Join(2000))
                {
                    _storageThread.Interrupt();
                }
            }

            // 处理剩余缓冲数据
            if (_batchBuffer.Count > 0)
            {
                WriteBatchToExcel();
            }
            Console.WriteLine("Excel存储线程已停止");
        }

        public static bool EnqueueData(SingleItemInfo item)
        {
            Console.WriteLine("存储");
            lock (_lock)
            {
                try
                {
                    _dataQueue.Add(item);
                    if (_dataQueue.Count % 50 == 0)
                    {
                        Console.WriteLine($"[Excel存储] 队列深度: {_dataQueue.Count}");
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"添加到队列失败: {ex.Message}");
                    return false;
                }
            }
        }

        private static void StorageThreadProc()
        {
            Console.WriteLine("Excel存储线程开始运行");

            while (_isRunning || !_dataQueue.IsCompleted)
            {
                if (_dataQueue.TryTake(out var item, 1000))
                {
                    lock (_batchBuffer)
                    {
                        _batchBuffer.Add(item);
                        if (_batchBuffer.Count >= BATCH_SIZE)
                        {
                            WriteBatchToExcel();
                        }
                    }
                }
                else if (!_isRunning)
                {
                    break;
                }
            }
        }

        // 获取当前月份文件夹路径
        private static string GetCurrentMonthDirectory()
        {
            // 按月组织：yyyy-MM格式
            string monthFolder = DateTime.Today.ToString("yyyy-MM");
            string monthPath = Path.Combine(_baseDataDirectory, monthFolder);

            // 确保月份目录存在
            if (!Directory.Exists(monthPath))
            {
                Directory.CreateDirectory(monthPath);
            }

            return monthPath;
        }

        // 获取当前Excel文件路径
        private static string GetExcelFilePath()
        {
            string monthPath = GetCurrentMonthDirectory();
            return Path.Combine(monthPath, $"InspectionData_{DateTime.Today:yyyyMMdd}.xlsx");
        }

        private static void WriteBatchToExcel()
        {
            if (_batchBuffer.Count == 0) return;

            int retryCount = 0;
            const int MAX_RETRY = 3;
            List<SingleItemInfo> currentBatch = new List<SingleItemInfo>(_batchBuffer);
            _batchBuffer.Clear();

            // 每次写入时获取当前的文件路径（确保目录存在）
            string excelFilePath = GetExcelFilePath();

            while (retryCount < MAX_RETRY)
            {
                try
                {
                    var fileInfo = new FileInfo(excelFilePath);
                    using (var package = new ExcelPackage(fileInfo))
                    {
                        // 获取或创建工作表
                        var worksheet = package.Workbook.Worksheets["检测数据"] ??
                                        package.Workbook.Worksheets.Add("检测数据");

                        // 初始化表头（仅当新创建时）
                        if (worksheet.Dimension == null)
                        {
                            var headers = new[]
                            {
                                "产品ID", "产品名称",
                                "工位一检测时间", "工位一位置", "工位一照片宽度", "工位一照片高度",
                                "工位一图片名称", "工位一缺陷类型", "是否不良", "是否保存",
                                "工位二检测时间", "工位二位置", "工位二照片宽度", "工位二照片高度",
                                "工位二图片名称", "工位二缺陷类型", "是否不良", "是否保存",
                                "工位三检测时间", "工位三位置", "工位三照片宽度", "工位三照片高度",
                                "工位三图片名称", "工位三缺陷类型", "是否不良", "是否保存"
                            };

                            for (int i = 0; i < headers.Length; i++)
                            {
                                worksheet.Cells[1, i + 1].Value = headers[i];
                                worksheet.Cells[1, i + 1].Style.Font.Bold = true;
                            }
                        }

                        // 计算数据起始行（追加到现有数据末尾）
                        int startRow = worksheet.Dimension?.End.Row + 1 ?? 2;

                        // 批量写入数据
                        for (int i = 0; i < currentBatch.Count; i++)
                        {
                            var item = currentBatch[i];
                            int currentRow = startRow + i;

                            // 确保有足够的行
                            if (currentRow > worksheet.Dimension?.Rows)
                            {
                                worksheet.InsertRow(currentRow, 1);
                            }

                            worksheet.Cells[currentRow, 1].Value = item.SampleId; // 使用SampleId作为产品ID
                            worksheet.Cells[currentRow, 2].Value = item.Name;

                            // 工位一数据
                            worksheet.Cells[currentRow, 3].Value = item.CameraResult01.DataTime;
                            worksheet.Cells[currentRow, 4].Value = item.CameraResult01.Location;
                            worksheet.Cells[currentRow, 5].Value = item.CameraResult01.iWidth;
                            worksheet.Cells[currentRow, 6].Value = item.CameraResult01.iHeight;
                            worksheet.Cells[currentRow, 7].Value = item.CameraResult01.iName;
                            worksheet.Cells[currentRow, 8].Value = item.CameraResult01.Faults;
                            worksheet.Cells[currentRow, 9].Value = item.CameraResult01.isNG == true ? "NG" : "OK";
                            worksheet.Cells[currentRow, 10].Value = item.CameraResult01.isOkSave == true ? "是" : "否";

                            // 工位二数据（确保索引正确）
                            worksheet.Cells[currentRow, 11].Value = item.CameraResult02.DataTime;
                            worksheet.Cells[currentRow, 12].Value = item.CameraResult02.Location;
                            worksheet.Cells[currentRow, 13].Value = item.CameraResult02.iWidth;
                            worksheet.Cells[currentRow, 14].Value = item.CameraResult02.iHeight;
                            worksheet.Cells[currentRow, 15].Value = item.CameraResult02.iName;
                            worksheet.Cells[currentRow, 16].Value = item.CameraResult02.Faults;
                            worksheet.Cells[currentRow, 17].Value = item.CameraResult02.isNG == true ? "NG" : "OK";
                            worksheet.Cells[currentRow, 18].Value = item.CameraResult02.isOkSave == true ? "是" : "否";

                            // 工位三数据（确保索引正确）
                            worksheet.Cells[currentRow, 19].Value = item.CameraResult03.DataTime;
                            worksheet.Cells[currentRow, 20].Value = item.CameraResult03.Location;
                            worksheet.Cells[currentRow, 21].Value = item.CameraResult03.iWidth;
                            worksheet.Cells[currentRow, 22].Value = item.CameraResult03.iHeight;
                            worksheet.Cells[currentRow, 23].Value = item.CameraResult03.iName;
                            worksheet.Cells[currentRow, 24].Value = item.CameraResult03.Faults;
                            worksheet.Cells[currentRow, 25].Value = item.CameraResult03.isNG == true ? "NG" : "OK";
                            worksheet.Cells[currentRow, 26].Value = item.CameraResult03.isOkSave == true ? "是" : "否";
                        }

                        // 保存文件
                        package.Save();
                    }

                    Console.WriteLine($"[Excel存储] 成功写入 {currentBatch.Count} 条数据到 {excelFilePath}");
                    return;
                }
                catch (Exception ex)
                {
                    retryCount++;
                    Console.WriteLine($"[Excel存储] 写入失败(重试 {retryCount}/{MAX_RETRY}): {ex.Message}");
                    Thread.Sleep(1000 * retryCount);
                }
            }

            Console.WriteLine($"[严重错误] 无法写入Excel，丢失 {currentBatch.Count} 条数据");
        }
    }
}